﻿using NewLife;
using NewLife.Reflection;
using NewLife.RocketMQ;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using IntelligentEscalator.DAL;
using IntelligentEscalator.Models;

namespace IntelligentEscalator.BUS.RocketMQ
{
    public class FXMQClient
    {
        public string aes_key = string.Empty;
        public string server_addr = string.Empty;
        public string IdentityTopic = string.Empty;
        public string ThirdPartyTopic = string.Empty;
        public string PanoramicTopic = string.Empty;
        public string version = string.Empty;
        public string AccessKey = string.Empty;
        public string SecretKey = string.Empty;
        public Consumer Identity_consumer;
        public Consumer ThirdParty_consumer;
        public static Producer Producer = new Producer();
        public bool Identity_flag = false;
        public bool ThirdParty_flag = false;
        public FXMQClient()
        {
            aes_key = AppSettingsHelper.Configuration["MQ:PrivateKey"];
            server_addr = string.Format("{0}:{1}", AppSettingsHelper.Configuration["MQ:Server"], AppSettingsHelper.Configuration["MQ:Port"]);
            IdentityTopic = AppSettingsHelper.Configuration["MQ:IdentityTopic"];
            ThirdPartyTopic = AppSettingsHelper.Configuration["MQ:ThirdPartyTopic"];
            PanoramicTopic = AppSettingsHelper.Configuration["MQ:PanoramicTopic"];
            version = AppSettingsHelper.Configuration["MQ:Version"];
            AccessKey = AppSettingsHelper.Configuration["MQ:AccessKey"];
            SecretKey = AppSettingsHelper.Configuration["MQ:SecretKey"];
            try
            {
                Task t = Task.Factory.StartNew(async () =>
                {
                    while (true)
                    {
                        if (Identity_consumer == null || !Identity_flag)
                        {
                            IdentityInit();
                        }

                        if (ThirdParty_consumer == null || !ThirdParty_flag)
                        {
                            ThirdPartyInit();
                        }

                        if (!Producer.Active)
                        {
                            PanoramicInit();
                        }
                        Task.Delay(10000).Wait();

                    }
                });
            }
            catch (Exception ex)
            {

            }

        }

        private void IdentityInit()
        {
            try
            {
                Identity_consumer = new Consumer
                {
                    Topic = IdentityTopic,
                    //Group = "T01",
                    NameServerAddress = server_addr,
                    //设置每次接收消息只拉取一条信息
                    BatchSize = 1,
                    AccessKey = AccessKey,
                    SecretKey = SecretKey,
                    //FromLastOffset = true,
                    //SkipOverStoredMsgCount = 0,
                    //BatchSize = 20,
                    //Log = NewLife.Log.XTrace.Log,
                };
                Identity_consumer.OnConsume = (q, ms) =>
                {
                    foreach (var item in ms.ToList())
                    {
                        try
                        {
                            LogHelper.Log(item.Body.ToStr());
                            AuthInfo authInfo = JsonConvert.DeserializeObject<AuthInfo>(item.Body.ToStr());
                            if (authInfo != null)
                            {
                                if (authInfo.type == "org")
                                {
                                    AuthOrganizationInfo organizationInfo = JsonConvert.DeserializeObject<AuthOrganizationInfo>(item.Body.ToStr());
                                    if (organizationInfo != null)
                                    {
                                        OrganizationDAL organizationDAL = new OrganizationDAL();
                                        if (organizationInfo.operateType == "add")
                                        {
                                            int id = organizationDAL.QuerySyncOrganizationId(organizationInfo.id);
                                            if (id > 0)
                                            {
                                                organizationDAL.EditOrganizationById(organizationInfo, id);
                                            }
                                            else
                                            {
                                                organizationDAL.AddOrganization(organizationInfo);
                                            }
                                        }
                                        else if (organizationInfo.operateType == "update")
                                        {
                                            organizationDAL.EditOrganization(organizationInfo);
                                        }
                                        else if (organizationInfo.operateType == "delete")
                                        {
                                            organizationDAL.DelOrganization(organizationInfo);
                                        }
                                    }
                                }
                                else if (authInfo.type == "user")
                                {
                                    AuthAccountInfo authAccountInfo = JsonConvert.DeserializeObject<AuthAccountInfo>(item.Body.ToStr());
                                    if (authAccountInfo != null)
                                    {
                                        authAccountInfo.password = AESDecrypt(authAccountInfo.password, aes_key);
                                        UserRoleDAL userRoleDAL = new UserRoleDAL();
                                        if (authAccountInfo.operateType == "add")
                                        {
                                            int id = userRoleDAL.QueryAccount(authAccountInfo.id);
                                            if (id > 0)
                                            {
                                                userRoleDAL.EditSyncAccount(authAccountInfo, id);
                                            }
                                            else
                                            {
                                                userRoleDAL.AddAccount(authAccountInfo);
                                            }
                                        }
                                        else if (authAccountInfo.operateType == "update")
                                        {
                                            userRoleDAL.EditAccount(authAccountInfo);
                                        }
                                        else if (authAccountInfo.operateType == "delete")
                                        {
                                            userRoleDAL.DelAccount(authAccountInfo);
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {

                        }
                    }
                    return true;        //通知消息队：消费了消息
                };
                Identity_consumer.Start();
                Identity_flag = true;
            }
            catch (Exception ex)
            {
            }

        }

        private void ThirdPartyInit()
        {
            try
            {
                ThirdParty_consumer = new Consumer
                {
                    Topic = ThirdPartyTopic,
                    //Group = "T01",
                    NameServerAddress = server_addr,
                    //设置每次接收消息只拉取一条信息
                    BatchSize = 1,
                    AccessKey = AccessKey,
                    SecretKey = SecretKey,
                    //FromLastOffset = true,
                    //SkipOverStoredMsgCount = 0,
                    //BatchSize = 20,
                    //Log = NewLife.Log.XTrace.Log,
                };
                ThirdParty_consumer.OnConsume = (q, ms) =>
                {
                    foreach (var item in ms.ToList())
                    {
                        try
                        {
                            LogHelper.Log(item.Body.ToStr());
                            ThirdPartyData thirdPartyData = JsonConvert.DeserializeObject<ThirdPartyData>(item.Body.ToStr());
                            if (thirdPartyData != null)
                            {
                                if (thirdPartyData.dataType == version + "/DeviceStatusTotal/01" || thirdPartyData.dataType == version + "/DeviceStatusTotal/02" || thirdPartyData.dataType == version + "/DeviceStatusTotal/03")
                                {
                                    LogHelper.Log(thirdPartyData.data.ToString());
                                    DeviceStatusTotal deviceStatusTotal = JsonConvert.DeserializeObject<DeviceStatusTotal>(thirdPartyData.data.ToString());
                                    if (deviceStatusTotal != null)
                                    {
                                        MqttDataBUS mqttDataBUS = new MqttDataBUS();
                                        mqttDataBUS.MqttDataProcess(deviceStatusTotal, "DeviceStatusTotal", thirdPartyData.dataType.Substring(thirdPartyData.dataType.Length - 2, 2));
                                    }
                                }
                                else if (thirdPartyData.dataType == version + "/TodayProcess/01" || thirdPartyData.dataType == version + "/TodayProcess/02" || thirdPartyData.dataType == version + "/TodayProcess/03")
                                {
                                    MqttDataBUS mqttDataBUS = new MqttDataBUS();
                                    TodayProcess todayProcess = JsonConvert.DeserializeObject<TodayProcess>(thirdPartyData.data.ToString());
                                    if (todayProcess != null)
                                    {
                                        mqttDataBUS.MqttDataProcess(todayProcess, "TodayProcess", thirdPartyData.dataType.Substring(thirdPartyData.dataType.Length - 2, 2));
                                    }
                                }
                                else if (thirdPartyData.dataType == version + "/TodayRuntime/01" || thirdPartyData.dataType == version + "/TodayRuntime/02" || thirdPartyData.dataType == version + "/TodayRuntime/03")
                                {
                                    MqttDataBUS mqttDataBUS = new MqttDataBUS();
                                    TodayRuntime todayRuntime = JsonConvert.DeserializeObject<TodayRuntime>(thirdPartyData.data.ToString());
                                    if (todayRuntime != null)
                                    {
                                        string id = thirdPartyData.dataType.Substring(thirdPartyData.dataType.Length - 2, 2);
                                        string manufacturer = string.Empty;
                                        if (id == "01")
                                        {
                                            manufacturer = "Schindler";
                                        }
                                        else if (id == "02")
                                        {
                                            manufacturer = "TKE";
                                        }
                                        else
                                        {
                                            manufacturer = "TOSHIBA";
                                        }
                                        mqttDataBUS.MqttDataProcess(id, manufacturer, "TodayRuntime", todayRuntime.runtime);
                                    }
                                }
                                else if (thirdPartyData.dataType == version + "/FaultStatistics/01" || thirdPartyData.dataType == version + "/FaultStatistics/02" || thirdPartyData.dataType == version + "/FaultStatistics/03")
                                {
                                    MqttDataBUS mqttDataBUS = new MqttDataBUS();
                                    FaultStatistics faultStatistics = JsonConvert.DeserializeObject<FaultStatistics>(thirdPartyData.data.ToString());
                                    if (faultStatistics != null)
                                    {
                                        mqttDataBUS.MqttFaultStatistics(thirdPartyData.dataType.Substring(thirdPartyData.dataType.Length - 2, 2), "FaultStatistics", faultStatistics.faultTotal, faultStatistics.faultToday);
                                    }
                                }
                                else if (thirdPartyData.dataType == version + "/FaultRecordReport/01" || thirdPartyData.dataType == version + "/FaultRecordReport/02" || thirdPartyData.dataType == version + "/FaultRecordReport/03")
                                {
                                    MqttDataBUS mqttDataBUS = new MqttDataBUS();
                                    FaultRecordReport faultRecordReport = JsonConvert.DeserializeObject<FaultRecordReport>(thirdPartyData.data.ToString());
                                    if (faultRecordReport != null)
                                    {
                                        string id = thirdPartyData.dataType.Substring(thirdPartyData.dataType.Length - 2, 2);
                                        string manufacturer = string.Empty;
                                        if (id == "01")
                                        {
                                            faultRecordReport.manufacturer = "Schindler";
                                        }
                                        else if (id == "02")
                                        {
                                            faultRecordReport.manufacturer = "TKE";
                                        }
                                        else
                                        {
                                            faultRecordReport.manufacturer = "TOSHIBA";
                                        }

                                        mqttDataBUS.MqttFaultRecordDataProcess(faultRecordReport);
                                    }
                                }
                            }

                        }
                        catch (Exception ex)
                        {

                        }
                    }
                    return true;        //通知消息队：消费了消息
                };
                ThirdParty_consumer.Start();
                ThirdParty_flag = true;
            }
            catch (Exception ex)
            {
            }

        }

        private void PanoramicInit()
        {
            try
            {
                Producer = new Producer
                {
                    //主题
                    Topic = PanoramicTopic,
                    AccessKey = AccessKey,
                    SecretKey = SecretKey,
                    //服务地址
                    NameServerAddress = server_addr,
                };
                Producer.Start();
            }
            catch
            {
            }
        }

        public string AESDecrypt(string Data, string Key)
        {
            if (string.IsNullOrEmpty(Data))
            {
                return "";
            }
            Byte[] encryptedBytes = Convert.FromBase64String(Data);
            Byte[] bKey = new Byte[16];
            Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);

            MemoryStream mStream = new MemoryStream(encryptedBytes);
            RijndaelManaged aes = new RijndaelManaged();
            aes.Mode = CipherMode.ECB;
            aes.Padding = PaddingMode.None;
            aes.KeySize = 128;
            aes.Key = bKey;
            CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Read);
            try
            {
                byte[] tmp = new byte[encryptedBytes.Length + 32];
                int len = cryptoStream.Read(tmp, 0, encryptedBytes.Length + 32);
                byte[] ret = new byte[len];
                Array.Copy(tmp, 0, ret, 0, len);
                return Encoding.UTF8.GetString(ret);
            }
            finally
            {
                cryptoStream.Close();
                mStream.Close();
                aes.Clear();
            }
        }

        public void PushData()
        {

        }
    }
}
